-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CCIP-4160 Token Transfer Tests #15278
base: develop
Are you sure you want to change the base?
Conversation
AER Report: CI Core ran successfully ✅AER Report: Operator UI CI ran successfully ✅ |
99c3452
to
3bfac63
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job, some minor comments
integration-tests/smoke/ccip_test.go
Outdated
return srcToken, dstToken | ||
} | ||
|
||
func mintAndApprove(t *testing.T, e ccdeploy.DeployedEnv, state ccdeploy.CCIPOnChainState, token *burn_mint_erc677.BurnMintERC677, chainSel uint64, amount *big.Int) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we have a very similar helper for the USDC, it would be great to dedup these
func mintAndAllow( |
integration-tests/smoke/ccip_test.go
Outdated
// Fetch initial balance | ||
if _, exists := initialBalances[dstToken.Address()]; !exists { | ||
balance, err := dstToken.BalanceOf(nil, scenario.receiver) | ||
require.NoError(t, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar story already for USDC, if worth the effort / makes sense we can dedup this code
integration-tests/smoke/ccip_test.go
Outdated
}, | ||
}, | ||
receiver: e.Chains[tenv.FeedChainSel].DeployerKey.From, | ||
data: []byte(""), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest making data as nil or empty slice to make it more explicit
integration-tests/smoke/ccip_test.go
Outdated
_, err = e.Chains[tenv.HomeChainSel].Confirm(tx) | ||
require.NoError(t, err) | ||
// Deploy and approve tokens. | ||
srcToken1, dstToken1 := deployAndApproveTokens(t, tenv, state, "Token1") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it was part of the ticket to also deploy some tokens in self serve manner. Right now, we deploy everything using the DeployerKey
. We want to also verify it token transfers work properly in the self-serve deployed pool. Probably you need to create a new EOA and deploy token contracts from that
integration-tests/smoke/ccip_test.go
Outdated
dstChain uint64 | ||
tokenAmounts []router.ClientEVMTokenAmount | ||
receiver common.Address | ||
data []byte |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If data is always nil for this test, do we need this in the scenario?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For programmable token transfer tests data will not be nil right ?
# Conflicts: # integration-tests/smoke/ccip_test.go
# Conflicts: # integration-tests/smoke/ccip_test.go
# Conflicts: # integration-tests/smoke/ccip/ccip_test.go
# Conflicts: # integration-tests/smoke/ccip/ccip_test.go
# Conflicts: # integration-tests/smoke/ccip/ccip_test.go
…IP-4160_Implement_token_transfer_tests # Conflicts: # deployment/ccip/changeset/test_helpers.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly minor comments, approving. Feel free to resolve and re-request review if you agree with any.
for _, token := range tokens { | ||
twoCoins := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2)) | ||
|
||
owner, ok := owners[chain] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this could be moved in the outer loop.
expectedSeqNum := make(map[SourceDestPair]uint64) | ||
expectedSeqNumExec := make(map[SourceDestPair][]uint64) | ||
|
||
latesthdr, err := env.Chains[destChain].Client.HeaderByNumber(testcontext.Get(t), nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe better to pass ctx
to this func?
require.NoError(t, err) | ||
|
||
require.Eventually(t, func() bool { | ||
actualBalance, err := tokenContract.BalanceOf(&bind.CallOpts{Context: tests.Context(t)}, receiver) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe pass ctx
to this func? to avoid getting a new one everyime.
tokenContract, err := burn_mint_erc677.NewBurnMintERC677(token, chain.Client) | ||
require.NoError(t, err) | ||
|
||
balance, err := tokenContract.BalanceOf(&bind.CallOpts{Context: tests.Context(t)}, receiver) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similar for ctx
inMemoryEnv := false | ||
|
||
// use this if you are testing locally in memory | ||
// tenv := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 2, 4, config) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be better if we can do this using some env var. So we can easily switch in CI or run without touching code.
selfServeDestTokenPoolDeployer, | ||
state, | ||
e.ExistingAddresses, | ||
"SELF_SERVE_TOKEN", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
|
||
tinyOneCoin := new(big.Int).SetUint64(1) | ||
|
||
// Test scenarios are defined here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment probably not necessary, it's obvious
tokenAmounts: []router.ClientEVMTokenAmount{ | ||
{ | ||
Token: srcToken.Address(), | ||
Amount: tinyOneCoin, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name is a bit confusing for me tinyOneCoin
maybe just one
and oneE18
, fiveE18
etc ?
}, | ||
receiver: state.Chains[sourceChain].Receiver.Address(), | ||
expectedTokenBalances: map[common.Address]*big.Int{ | ||
selfServeSrcToken.Address(): new(big.Int).SetUint64(2), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can set two
to a variable to follow same pattern with tinyOneCoin
require.NoError(t, err) | ||
|
||
// Simulated backend sets chainID to 1337 always | ||
chainID := big.NewInt(1337) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i believe it's similar for the commented out environment setup.
@@ -75,134 +73,3 @@ func TestInitialDeployOnLocal(t *testing.T) { | |||
|
|||
// TODO: Apply the proposal. | |||
} | |||
|
|||
func TestTokenTransfer(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: As we moved out this test, the parallel count here can be reduced to one. https://github.com/smartcontractkit/chainlink/pull/15278/files#diff-c97a5a0f8e46926381c7f53223fb048419a40e9c9b8e243b3f49e15bc2e00d9eL945
for _, scenario := range scenarios { | ||
t.Run(scenario.name, func(t *testing.T) { | ||
initialBalances := map[common.Address]*big.Int{} | ||
for token := range scenario.expectedTokenBalances { | ||
initialBalance := changeset.GetTokenBalance(t, token, scenario.receiver, e.Chains[scenario.dstChain]) | ||
initialBalances[token] = initialBalance | ||
} | ||
|
||
changeset.TransferAndWaitForSuccess( | ||
t, | ||
e, | ||
state, | ||
scenario.srcChain, | ||
scenario.dstChain, | ||
scenario.tokenAmounts, | ||
scenario.receiver, | ||
scenario.data, | ||
scenario.expectedExecutionState, | ||
) | ||
|
||
for token, balance := range scenario.expectedTokenBalances { | ||
expected := new(big.Int).Add(initialBalances[token], balance) | ||
changeset.WaitForTheTokenBalance(t, token, scenario.receiver, e.Chains[scenario.dstChain], expected) | ||
} | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach is quite sequential. I would recommend splitting this test into multiple smaller tests and enabling parallel execution.
A few options we could consider include:
- Using multiple wallet addresses.
- Breaking the test into separate segments (though this will require repeating the setup), and assigning a dedicated runner for each segment. This would reduce the overall execution time, as the message processing wait time can be parallelized across the different tests. With this approach, we could potentially achieve at least a 3x speedup.
CCIP Integration test covering the following scenarios